// BlobsEfx.cpp: implementation of the CBlobsEfx class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BlobsEfx.h"

//////////////////////////////////////////////////////////////////////
// consts
//////////////////////////////////////////////////////////////////////

#define	BLOBSPLINES		27

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBlobsEfx::CBlobsEfx( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice ), m_bsSystem( 22 ),
												   m_pvbBackFx( NULL ),
												   m_pvbWireframeCube( NULL ),
												   m_pibWireframeCube( NULL ),
												   m_pvbSyncSphere( NULL ),
												   m_pibSyncSphere( NULL ),
												   m_piqFace( NULL ),
												   m_piqVis( NULL ),
												   m_piqDispaly( NULL )
{
	try
	{	
		LoadTexture( "env.jpg" );
		LoadAlphaTexture( "backfx.bmp" );
		LoadTexture( "face.jpg" );
		LoadAlphaTexture( "vis.bmp" );
		LoadAlphaTexture( "display3.bmp" );
		LoadAlphaTexture( "dispmask.bmp" );
	}
	catch( CTextureException )	
	{	
		throw CSystemException( "unable to load textures" );	
	}

	if( FAILED( m_pDevice->CreateVertexBuffer( 6*sizeof(LVERTEX), 0, FVF_LVERTEX, D3DPOOL_DEFAULT, &m_pvbBackFx ) ) )
		throw CSystemException( "unable to create back fx vertex buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 1000*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbWireframeCube ) ) )
		throw CSystemException( "unable to create wireframe cube vertex buffer" );

	if( FAILED( m_pDevice->CreateIndexBuffer( 5400*sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibWireframeCube ) ) )
		throw CSystemException( "unable to create wireframe cube index buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 8*38*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbSyncSphere ) ) )
		throw CSystemException( "unable to create sync sphere vertex buffer" );

	if( FAILED( m_pDevice->CreateIndexBuffer( 36*38*sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibSyncSphere ) ) )
		throw CSystemException( "unable to create sync sphere index buffer" );

	if( !m_bsSystem.Initialize( m_pDevice ) )	
		throw CSystemException( "unable to initialize blob system" );	
	
	if( !m_smGrid.Load( m_pDevice, "data\\objects\\grid.smf" ) )	
		throw CSystemException( "unable to load grid.smf" );	

	m_piqFace = new CImageQuad( m_pDevice, 0, 0, 0, 0 );
	m_piqVis  = new CImageQuad( m_pDevice, 0, 0, 0, 0 );
	m_piqDispaly = new CImageQuad( m_pDevice, 206, 262, 512, 512 );

	m_piqFace->SetARGB( 0x0 );
	m_piqVis->SetARGB( 0x0 );
	m_piqDispaly->SetARGB( 0x0 );
						
	for( DWORD i = 0 ; i < 27 ; i++ )
	{
		m_b3dBlobs[i].m_fDensity = 1.5f;
		m_b3dBlobs[i].m_fRadius = 0.8f;		

		m_bsSystem.AddBlob( &m_b3dBlobs[i] );
	}			

	LoadSplines();

	PLVERTEX				pVertices;

	m_pvbBackFx->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	*(pVertices++) = LVERTEX( -1.0f,  1.0f, 0.0f, 0x0, 0.0f, 0.0f );
	*(pVertices++) = LVERTEX(  1.0f, -1.0f, 0.0f, 0x0, 1.0f, 1.0f );
	*(pVertices++) = LVERTEX( -1.0f, -1.0f, 0.0f, 0x0, 0.0f, 1.0f );		

	*(pVertices++) = LVERTEX(  1.0f, -1.0f, 0.0f, 0x0, 1.0f, 1.0f );
	*(pVertices++) = LVERTEX( -1.0f,  1.0f, 0.0f, 0x0, 0.0f, 0.0f );
	*(pVertices++) = LVERTEX(  1.0f,  1.0f, 0.0f, 0x0, 1.0f, 0.0f );

	m_pvbBackFx->Unlock();

	PSIMPLEVERTEX			pVerts;
	LPWORD					pIndices;
	DWORD					dwIndex = 0;

	m_pvbWireframeCube->Lock( 0, 0, (LPBYTE*)&pVerts, 0 );

	for( i = 0 ; i < 10 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++ )
			for( DWORD k = 0 ; k < 10 ; k++, dwIndex++ )			
			{			
				m_vCube[dwIndex] = he3d_CVector( (FLOAT)k/9.0f - 0.5f, (FLOAT)j/9.0f - 0.5f, (FLOAT)i/9.0f - 0.5f );
				pVerts[dwIndex] = SIMPLEVERTEX( (FLOAT)k/9.0f - 0.5f, (FLOAT)j/9.0f - 0.5f, (FLOAT)i/9.0f - 0.5f, 0x80000000 );
			}

	m_pvbWireframeCube->Unlock();	

	m_pibWireframeCube->Lock( 0, 0, (LPBYTE*)&pIndices, 0 );

	for( i = 0 ; i < 100 ; i++ )
		for( DWORD j = 0 ; j < 9 ; j++ )
		{
			*(pIndices++) = (WORD)(i + 100*j);
			*(pIndices++) = (WORD)(i + 100*(j+1));
		}

	for( i = 0 ; i < 100 ; i++ )
		for( DWORD j = 0 ; j < 9 ; j++ )
		{
			*(pIndices++) = (WORD)(i*10 + j);
			*(pIndices++) = (WORD)(i*10 + (j+1));
		}

	for( i = 0 ; i < 10 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++ )
			for( DWORD k = 0 ; k < 9 ; k++ )
			{
				*(pIndices++) = (WORD)(i*100 + j + 10*k);
				*(pIndices++) = (WORD)(i*100 + j + 10*(k+1));
			}

	m_pibWireframeCube->Unlock();

	m_vEmiterPos = he3d_CVector( -0.25f, 0.0f, 0.0f );

	// syn sphere init

	he3d_CMatrix			mtx;

	m_pvbSyncSphere->Lock( 0, 0, (LPBYTE*)&pVerts, 0 );

	for( i = 0 ; i < 2 ; i++ )
	{	
		dwIndex = 0;

		for( DWORD j = 0 ; j < 6 ; j++ )
			for( DWORD k = 0 ; k < 6 ; k++ )
			{			
				mtx = XRotationMtx( (FLOAT)(k+1)*H_PI/7.0f )*YRotationMtx( (FLOAT)j*H_2PI/6.0f );			
		
				*(pVerts++) = SIMPLEVERTEX( he3d_CVector( -0.1f, 1.0f,  0.1f )*mtx, 0x0 );
				*(pVerts++) = SIMPLEVERTEX( he3d_CVector( -0.1f, 1.0f, -0.1f )*mtx, 0x0 );
				*(pVerts++) = SIMPLEVERTEX( he3d_CVector(  0.1f, 1.0f, -0.1f )*mtx, 0x0 );
				*(pVerts++) = SIMPLEVERTEX( he3d_CVector(  0.1f, 1.0f,  0.1f )*mtx, 0x0 );

				m_vSphere[dwIndex][0] = he3d_CVector( -0.1f, 1.0f,  0.1f )*mtx;
				m_vSphere[dwIndex][1] = he3d_CVector( -0.1f, 1.0f, -0.1f )*mtx;
				m_vSphere[dwIndex][2] = he3d_CVector(  0.1f, 1.0f, -0.1f )*mtx;
				m_vSphere[dwIndex][3] = he3d_CVector(  0.1f, 1.0f,  0.1f )*mtx;

				m_vSphereVector[dwIndex++] = he3d_CVector( 0.0f, 1.0f, 0.0f )*mtx;
			}		
	
		mtx = XRotationMtx( 0.0f )*YRotationMtx( 0.0f );	

		*(pVerts++) = SIMPLEVERTEX( he3d_CVector( -0.1f, 1.0f,  0.1f )*mtx, 0x0 );
		*(pVerts++) = SIMPLEVERTEX( he3d_CVector( -0.1f, 1.0f, -0.1f )*mtx, 0x0 );
		*(pVerts++) = SIMPLEVERTEX( he3d_CVector(  0.1f, 1.0f, -0.1f )*mtx, 0x0 );
		*(pVerts++) = SIMPLEVERTEX( he3d_CVector(  0.1f, 1.0f,  0.1f )*mtx, 0x0 );

		m_vSphere[dwIndex][0] = he3d_CVector( -0.1f, 1.0f,  0.1f )*mtx;
		m_vSphere[dwIndex][1] = he3d_CVector( -0.1f, 1.0f, -0.1f )*mtx;
		m_vSphere[dwIndex][2] = he3d_CVector(  0.1f, 1.0f, -0.1f )*mtx;
		m_vSphere[dwIndex][3] = he3d_CVector(  0.1f, 1.0f,  0.1f )*mtx;

		m_vSphereVector[dwIndex++] = he3d_CVector( 0.0f, 1.0f, 0.0f )*mtx;

		mtx = XRotationMtx( H_PI )*YRotationMtx( 0.0f );

		*(pVerts++) = SIMPLEVERTEX( he3d_CVector( -0.1f, 1.0f,  0.1f )*mtx, 0x0 );
		*(pVerts++) = SIMPLEVERTEX( he3d_CVector( -0.1f, 1.0f, -0.1f )*mtx, 0x0 );
		*(pVerts++) = SIMPLEVERTEX( he3d_CVector(  0.1f, 1.0f, -0.1f )*mtx, 0x0 );
		*(pVerts++) = SIMPLEVERTEX( he3d_CVector(  0.1f, 1.0f,  0.1f )*mtx, 0x0 );

		m_vSphere[dwIndex][0] = he3d_CVector( -0.1f, 1.0f,  0.1f )*mtx;
		m_vSphere[dwIndex][1] = he3d_CVector( -0.1f, 1.0f, -0.1f )*mtx;
		m_vSphere[dwIndex][2] = he3d_CVector(  0.1f, 1.0f, -0.1f )*mtx;
		m_vSphere[dwIndex][3] = he3d_CVector(  0.1f, 1.0f,  0.1f )*mtx;

		m_vSphereVector[dwIndex++] = he3d_CVector( 0.0f, 1.0f, 0.0f )*mtx;
	}

	m_pvbSyncSphere->Unlock();

	for( i = 0 ; i < 38 ; i++ )
		m_dwSyncIndex[i] = rand()%6;

	m_pibSyncSphere->Lock( 0, 0, (LPBYTE*)&pIndices, 0 );

	for( i = 0 ; i < 38 ; i++ )
	{
		*(pIndices++) = (WORD)( i*4 + 0 );
		*(pIndices++) = (WORD)( i*4 + 3 );
		*(pIndices++) = (WORD)( i*4 + 1 );

		*(pIndices++) = (WORD)( i*4 + 3 );
		*(pIndices++) = (WORD)( i*4 + 2 );
		*(pIndices++) = (WORD)( i*4 + 1 );

		//!!

		*(pIndices++) = (WORD)( i*4 + 0 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 1 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 3 + 38*4 );

		*(pIndices++) = (WORD)( i*4 + 3 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 1 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 2 + 38*4 );

		//!!

		*(pIndices++) = (WORD)( i*4 + 0 );
		*(pIndices++) = (WORD)( i*4 + 1 );
		*(pIndices++) = (WORD)( i*4 + 1 + 38*4 );

		*(pIndices++) = (WORD)( i*4 + 0 );
		*(pIndices++) = (WORD)( i*4 + 1 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 0 + 38*4 );

		//!!

		*(pIndices++) = (WORD)( i*4 + 3 );
		*(pIndices++) = (WORD)( i*4 + 2 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 2 );		

		*(pIndices++) = (WORD)( i*4 + 3 );
		*(pIndices++) = (WORD)( i*4 + 3 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 2 + 38*4 );

		//!!

		*(pIndices++) = (WORD)( i*4 + 2 );
		*(pIndices++) = (WORD)( i*4 + 2 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 1 + 38*4 );

		*(pIndices++) = (WORD)( i*4 + 1 );
		*(pIndices++) = (WORD)( i*4 + 2 );
		*(pIndices++) = (WORD)( i*4 + 1 + 38*4 );

		//!!

		*(pIndices++) = (WORD)( i*4 + 3 );
		*(pIndices++) = (WORD)( i*4 + 0 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 3 + 38*4 );		

		*(pIndices++) = (WORD)( i*4 + 0 );
		*(pIndices++) = (WORD)( i*4 + 0 + 38*4 );
		*(pIndices++) = (WORD)( i*4 + 3 );		
	}

	m_pibSyncSphere->Unlock();

	//=============================================================================================
	// sync splines
	//=============================================================================================

	m_fSync[0][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[0][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[0][ 2] = FLOATKEY(  1.24f,  0.00f );
	m_fSync[0][ 3] = FLOATKEY(  1.44f,  1.00f );
	m_fSync[0][ 4] = FLOATKEY(  1.64f,  0.00f );
	m_fSync[0][ 5] = FLOATKEY(  3.74f,  0.00f );
	m_fSync[0][ 6] = FLOATKEY(  3.94f,  1.00f );
	m_fSync[0][ 7] = FLOATKEY(  4.14f,  0.00f );
	m_fSync[0][ 8] = FLOATKEY(  5.09f,  0.00f );
	m_fSync[0][ 9] = FLOATKEY(  5.29f,  1.00f );
	m_fSync[0][10] = FLOATKEY(  5.40f,  0.00f );
	m_fSync[0][11] = FLOATKEY(  5.51f,  1.00f );
	m_fSync[0][12] = FLOATKEY(  5.71f,  0.00f );
	m_fSync[0][13] = FLOATKEY( 10.23f,  0.00f );
	m_fSync[0][14] = FLOATKEY( 10.43f,  1.00f );
	m_fSync[0][15] = FLOATKEY( 10.63f,  0.00f );
	m_fSync[0][16] = FLOATKEY( 17.97f,  0.00f );
	m_fSync[0][17] = FLOATKEY( 18.17f,  1.00f );
	m_fSync[0][18] = FLOATKEY( 18.37f,  0.00f );
	m_fSync[0][19] = FLOATKEY( 18.40f,  0.00f );
	m_fSync[0][20] = FLOATKEY( 18.60f,  1.00f );
	m_fSync[0][21] = FLOATKEY( 18.80f,  0.00f );
	m_fSync[0][22] = FLOATKEY( 19.07f,  0.00f );
	m_fSync[0][23] = FLOATKEY( 19.27f,  1.00f );
	m_fSync[0][24] = FLOATKEY( 19.47f,  0.00f );
	m_fSync[0][25] = FLOATKEY( 20.74f,  0.00f );
	m_fSync[0][26] = FLOATKEY( 20.94f,  1.00f );
	m_fSync[0][27] = FLOATKEY( 21.14f,  0.00f );
	m_fSync[0][28] = FLOATKEY( 21.93f,  0.00f );
	m_fSync[0][29] = FLOATKEY( 22.13f,  1.00f );
	m_fSync[0][30] = FLOATKEY( 22.33f,  0.00f );
	m_fSync[0][31] = FLOATKEY( 22.46f,  0.00f );
	m_fSync[0][32] = FLOATKEY( 22.66f,  1.00f );
	m_fSync[0][33] = FLOATKEY( 22.86f,  0.00f );
	m_fSync[0][34] = FLOATKEY( 24.18f,  0.00f );
	m_fSync[0][35] = FLOATKEY( 24.38f,  1.00f );
	m_fSync[0][36] = FLOATKEY( 24.51f,  0.00f );
	m_fSync[0][37] = FLOATKEY( 24.63f,  1.00f );
	m_fSync[0][38] = FLOATKEY( 24.83f,  0.00f );


	InitFloatSpline( 39, m_fSync[0] );

	m_fSync[1][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[1][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[1][ 2] = FLOATKEY(  0.76f,  0.00f );
	m_fSync[1][ 3] = FLOATKEY(  0.96f,  1.00f );
	m_fSync[1][ 4] = FLOATKEY(  1.16f,  0.00f );
	m_fSync[1][ 5] = FLOATKEY(  2.15f,  0.00f );
	m_fSync[1][ 6] = FLOATKEY(  2.35f,  1.00f );
	m_fSync[1][ 7] = FLOATKEY(  2.55f,  0.00f );
	m_fSync[1][ 8] = FLOATKEY(  3.26f,  0.00f );
	m_fSync[1][ 9] = FLOATKEY(  3.46f,  1.00f );
	m_fSync[1][10] = FLOATKEY(  3.66f,  0.00f );
	m_fSync[1][11] = FLOATKEY(  4.19f,  0.00f );
	m_fSync[1][12] = FLOATKEY(  4.39f,  1.00f );
	m_fSync[1][13] = FLOATKEY(  4.59f,  0.00f );
	m_fSync[1][14] = FLOATKEY(  5.75f,  0.00f );
	m_fSync[1][15] = FLOATKEY(  5.95f,  1.00f );
	m_fSync[1][16] = FLOATKEY(  6.15f,  0.00f );
	m_fSync[1][17] = FLOATKEY(  6.92f,  0.00f );
	m_fSync[1][18] = FLOATKEY(  7.12f,  1.00f );
	m_fSync[1][19] = FLOATKEY(  7.32f,  0.00f );
	m_fSync[1][20] = FLOATKEY(  8.90f,  0.00f );
	m_fSync[1][21] = FLOATKEY(  9.10f,  1.00f );
	m_fSync[1][22] = FLOATKEY(  9.30f,  0.00f );
	m_fSync[1][23] = FLOATKEY(  9.79f,  0.00f );
	m_fSync[1][24] = FLOATKEY(  9.99f,  1.00f );
	m_fSync[1][25] = FLOATKEY( 10.19f,  0.00f );
	m_fSync[1][26] = FLOATKEY( 10.90f,  0.00f );
	m_fSync[1][27] = FLOATKEY( 11.10f,  1.00f );
	m_fSync[1][28] = FLOATKEY( 11.30f,  0.00f );
	m_fSync[1][29] = FLOATKEY( 16.58f,  0.00f );
	m_fSync[1][30] = FLOATKEY( 16.78f,  1.00f );
	m_fSync[1][31] = FLOATKEY( 16.98f,  0.00f );
	m_fSync[1][32] = FLOATKEY( 17.24f,  0.00f );
	m_fSync[1][33] = FLOATKEY( 17.44f,  1.00f );
	m_fSync[1][34] = FLOATKEY( 17.64f,  0.00f );
	m_fSync[1][35] = FLOATKEY( 19.51f,  0.00f );
	m_fSync[1][36] = FLOATKEY( 19.71f,  1.00f );
	m_fSync[1][37] = FLOATKEY( 19.91f,  0.00f );
	m_fSync[1][38] = FLOATKEY( 21.52f,  0.00f );
	m_fSync[1][39] = FLOATKEY( 21.72f,  1.00f );
	m_fSync[1][40] = FLOATKEY( 21.92f,  0.00f );
	m_fSync[1][41] = FLOATKEY( 23.12f,  0.00f );
	m_fSync[1][42] = FLOATKEY( 23.32f,  1.00f );
	m_fSync[1][43] = FLOATKEY( 23.52f,  0.00f );
	m_fSync[1][44] = FLOATKEY( 25.11f,  0.00f );
	m_fSync[1][45] = FLOATKEY( 25.31f,  1.00f );
	m_fSync[1][46] = FLOATKEY( 25.51f,  0.00f );
	m_fSync[1][47] = FLOATKEY( 25.79f,  0.00f );
	m_fSync[1][48] = FLOATKEY( 25.99f,  1.00f );
	m_fSync[1][49] = FLOATKEY( 26.19f,  0.00f );


	InitFloatSpline( 50, m_fSync[1] );

	m_fSync[2][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[2][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[2][ 2] = FLOATKEY(  2.85f,  0.00f );
	m_fSync[2][ 3] = FLOATKEY(  3.05f,  1.00f );
	m_fSync[2][ 4] = FLOATKEY(  3.25f,  0.00f );
	m_fSync[2][ 5] = FLOATKEY(  4.65f,  0.00f );
	m_fSync[2][ 6] = FLOATKEY(  4.85f,  1.00f );
	m_fSync[2][ 7] = FLOATKEY(  5.05f,  0.00f );
	m_fSync[2][ 8] = FLOATKEY(  6.31f,  0.00f );
	m_fSync[2][ 9] = FLOATKEY(  6.51f,  1.00f );
	m_fSync[2][10] = FLOATKEY(  6.71f,  0.00f );
	m_fSync[2][11] = FLOATKEY(  7.35f,  0.00f );
	m_fSync[2][12] = FLOATKEY(  7.55f,  1.00f );
	m_fSync[2][13] = FLOATKEY(  7.75f,  0.00f );
	m_fSync[2][14] = FLOATKEY(  8.25f,  0.00f );
	m_fSync[2][15] = FLOATKEY(  8.45f,  1.00f );
	m_fSync[2][16] = FLOATKEY(  8.65f,  0.00f );
	m_fSync[2][17] = FLOATKEY( 12.54f,  0.00f );
	m_fSync[2][18] = FLOATKEY( 12.74f,  1.00f );
	m_fSync[2][19] = FLOATKEY( 12.94f,  0.00f );
	m_fSync[2][20] = FLOATKEY( 13.00f,  0.00f );
	m_fSync[2][21] = FLOATKEY( 13.20f,  1.00f );
	m_fSync[2][22] = FLOATKEY( 13.40f,  0.00f );
	m_fSync[2][23] = FLOATKEY( 13.44f,  0.00f );
	m_fSync[2][24] = FLOATKEY( 13.64f,  1.00f );
	m_fSync[2][25] = FLOATKEY( 13.84f,  0.00f );
	m_fSync[2][26] = FLOATKEY( 13.88f,  0.00f );
	m_fSync[2][27] = FLOATKEY( 14.08f,  1.00f );
	m_fSync[2][28] = FLOATKEY( 14.28f,  0.00f );
	m_fSync[2][29] = FLOATKEY( 14.34f,  0.00f );
	m_fSync[2][30] = FLOATKEY( 14.54f,  1.00f );
	m_fSync[2][31] = FLOATKEY( 14.74f,  0.00f );
	m_fSync[2][32] = FLOATKEY( 14.79f,  0.00f );
	m_fSync[2][33] = FLOATKEY( 14.99f,  1.00f );
	m_fSync[2][34] = FLOATKEY( 15.19f,  0.00f );
	m_fSync[2][35] = FLOATKEY( 15.25f,  0.00f );
	m_fSync[2][36] = FLOATKEY( 15.45f,  1.00f );
	m_fSync[2][37] = FLOATKEY( 15.65f,  0.00f );
	m_fSync[2][38] = FLOATKEY( 15.69f,  0.00f );
	m_fSync[2][39] = FLOATKEY( 15.89f,  1.00f );
	m_fSync[2][40] = FLOATKEY( 16.09f,  0.00f );
	m_fSync[2][41] = FLOATKEY( 16.12f,  0.00f );
	m_fSync[2][42] = FLOATKEY( 16.32f,  1.00f );
	m_fSync[2][43] = FLOATKEY( 16.52f,  0.00f );
	m_fSync[2][44] = FLOATKEY( 20.19f,  0.00f );
	m_fSync[2][45] = FLOATKEY( 20.39f,  1.00f );
	m_fSync[2][46] = FLOATKEY( 20.59f,  0.00f );
	m_fSync[2][47] = FLOATKEY( 23.54f,  0.00f );
	m_fSync[2][48] = FLOATKEY( 23.74f,  1.00f );
	m_fSync[2][49] = FLOATKEY( 23.94f,  0.00f );
	m_fSync[2][50] = FLOATKEY( 26.24f,  0.00f );
	m_fSync[2][51] = FLOATKEY( 26.44f,  1.00f );
	m_fSync[2][52] = FLOATKEY( 26.64f,  0.00f );


	InitFloatSpline( 53, m_fSync[2] );

	m_fSync[3][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[3][ 1] = FLOATKEY(  0.05f,  0.00f );
	m_fSync[3][ 2] = FLOATKEY(  0.10f,  1.00f );
	m_fSync[3][ 3] = FLOATKEY(  0.25f,  0.00f );
	m_fSync[3][ 4] = FLOATKEY(  0.39f,  1.00f );
	m_fSync[3][ 5] = FLOATKEY(  0.47f,  0.00f );
	m_fSync[3][ 6] = FLOATKEY(  0.54f,  1.00f );
	m_fSync[3][ 7] = FLOATKEY(  0.67f,  0.00f );
	m_fSync[3][ 8] = FLOATKEY(  0.80f,  1.00f );
	m_fSync[3][ 9] = FLOATKEY(  1.00f,  0.00f );
	m_fSync[3][10] = FLOATKEY(  1.95f,  0.00f );
	m_fSync[3][11] = FLOATKEY(  2.15f,  1.00f );
	m_fSync[3][12] = FLOATKEY(  2.35f,  0.00f );
	m_fSync[3][13] = FLOATKEY(  3.08f,  0.00f );
	m_fSync[3][14] = FLOATKEY(  3.28f,  1.00f );
	m_fSync[3][15] = FLOATKEY(  3.48f,  0.00f );
	m_fSync[3][16] = FLOATKEY(  4.43f,  0.00f );
	m_fSync[3][17] = FLOATKEY(  4.63f,  1.00f );
	m_fSync[3][18] = FLOATKEY(  4.82f,  0.00f );
	m_fSync[3][19] = FLOATKEY(  6.25f,  0.00f );
	m_fSync[3][20] = FLOATKEY(  6.45f,  1.00f );
	m_fSync[3][21] = FLOATKEY(  6.55f,  0.00f );
	m_fSync[3][22] = FLOATKEY(  6.66f,  1.00f );
	m_fSync[3][23] = FLOATKEY(  6.86f,  0.00f );
	m_fSync[3][24] = FLOATKEY(  7.59f,  0.00f );
	m_fSync[3][25] = FLOATKEY(  7.79f,  1.00f );
	m_fSync[3][26] = FLOATKEY(  7.99f,  0.00f );
	m_fSync[3][27] = FLOATKEY(  8.03f,  0.00f );
	m_fSync[3][28] = FLOATKEY(  8.23f,  1.00f );
	m_fSync[3][29] = FLOATKEY(  8.43f,  0.00f );
	m_fSync[3][30] = FLOATKEY(  9.12f,  0.00f );
	m_fSync[3][31] = FLOATKEY(  9.32f,  1.00f );
	m_fSync[3][32] = FLOATKEY(  9.52f,  0.00f );
	m_fSync[3][33] = FLOATKEY( 10.02f,  0.00f );
	m_fSync[3][34] = FLOATKEY( 10.22f,  1.00f );
	m_fSync[3][35] = FLOATKEY( 10.42f,  0.00f );
	m_fSync[3][36] = FLOATKEY( 11.15f,  0.00f );
	m_fSync[3][37] = FLOATKEY( 11.35f,  1.00f );
	m_fSync[3][38] = FLOATKEY( 11.55f,  0.00f );
	m_fSync[3][39] = FLOATKEY( 17.01f,  0.00f );
	m_fSync[3][40] = FLOATKEY( 17.21f,  1.00f );
	m_fSync[3][41] = FLOATKEY( 17.41f,  0.00f );
	m_fSync[3][42] = FLOATKEY( 17.49f,  0.00f );
	m_fSync[3][43] = FLOATKEY( 17.69f,  1.00f );
	m_fSync[3][44] = FLOATKEY( 17.89f,  0.00f );
	m_fSync[3][45] = FLOATKEY( 19.25f,  0.00f );
	m_fSync[3][46] = FLOATKEY( 19.45f,  1.00f );
	m_fSync[3][47] = FLOATKEY( 19.65f,  0.00f );
	m_fSync[3][48] = FLOATKEY( 21.73f,  0.00f );
	m_fSync[3][49] = FLOATKEY( 21.93f,  1.00f );
	m_fSync[3][50] = FLOATKEY( 22.13f,  0.00f );
	m_fSync[3][51] = FLOATKEY( 23.32f,  0.00f );
	m_fSync[3][52] = FLOATKEY( 23.52f,  1.00f );
	m_fSync[3][53] = FLOATKEY( 23.72f,  0.00f );
	m_fSync[3][54] = FLOATKEY( 24.90f,  0.00f );
	m_fSync[3][55] = FLOATKEY( 25.10f,  1.00f );
	m_fSync[3][56] = FLOATKEY( 25.30f,  0.00f );
	m_fSync[3][57] = FLOATKEY( 26.04f,  0.00f );
	m_fSync[3][58] = FLOATKEY( 26.24f,  1.00f );
	m_fSync[3][59] = FLOATKEY( 26.44f,  0.00f );


	InitFloatSpline( 60, m_fSync[3] );

	m_fSync[4][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[4][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[4][ 2] = FLOATKEY(  1.04f,  0.00f );
	m_fSync[4][ 3] = FLOATKEY(  1.24f,  1.00f );
	m_fSync[4][ 4] = FLOATKEY(  1.44f,  0.00f );
	m_fSync[4][ 5] = FLOATKEY(  2.60f,  0.00f );
	m_fSync[4][ 6] = FLOATKEY(  2.80f,  1.00f );
	m_fSync[4][ 7] = FLOATKEY(  3.00f,  0.00f );
	m_fSync[4][ 8] = FLOATKEY(  3.94f,  0.00f );
	m_fSync[4][ 9] = FLOATKEY(  4.14f,  1.00f );
	m_fSync[4][10] = FLOATKEY(  4.34f,  0.00f );
	m_fSync[4][11] = FLOATKEY(  7.14f,  0.00f );
	m_fSync[4][12] = FLOATKEY(  7.34f,  1.00f );
	m_fSync[4][13] = FLOATKEY(  7.54f,  0.00f );
	m_fSync[4][14] = FLOATKEY( 10.50f,  0.00f );
	m_fSync[4][15] = FLOATKEY( 10.70f,  1.00f );
	m_fSync[4][16] = FLOATKEY( 10.79f,  0.00f );
	m_fSync[4][17] = FLOATKEY( 10.89f,  1.00f );
	m_fSync[4][18] = FLOATKEY( 11.09f,  0.00f );
	m_fSync[4][19] = FLOATKEY( 18.19f,  0.00f );
	m_fSync[4][20] = FLOATKEY( 18.39f,  1.00f );
	m_fSync[4][21] = FLOATKEY( 18.59f,  0.00f );
	m_fSync[4][22] = FLOATKEY( 18.87f,  0.00f );
	m_fSync[4][23] = FLOATKEY( 19.07f,  1.00f );
	m_fSync[4][24] = FLOATKEY( 19.27f,  0.00f );
	m_fSync[4][25] = FLOATKEY( 20.62f,  0.00f );
	m_fSync[4][26] = FLOATKEY( 20.82f,  1.00f );
	m_fSync[4][27] = FLOATKEY( 20.94f,  0.00f );
	m_fSync[4][28] = FLOATKEY( 21.05f,  1.00f );
	m_fSync[4][29] = FLOATKEY( 21.25f,  0.00f );
	m_fSync[4][30] = FLOATKEY( 22.41f,  0.00f );
	m_fSync[4][31] = FLOATKEY( 22.61f,  1.00f );
	m_fSync[4][32] = FLOATKEY( 22.74f,  0.00f );
	m_fSync[4][33] = FLOATKEY( 22.88f,  1.00f );
	m_fSync[4][34] = FLOATKEY( 23.08f,  0.00f );
	m_fSync[4][35] = FLOATKEY( 24.35f,  0.00f );
	m_fSync[4][36] = FLOATKEY( 24.55f,  1.00f );
	m_fSync[4][37] = FLOATKEY( 24.75f,  0.00f );


	InitFloatSpline( 38, m_fSync[4] );

	m_fSync[5][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[5][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[5][ 2] = FLOATKEY(  1.49f,  0.00f );
	m_fSync[5][ 3] = FLOATKEY(  1.69f,  1.00f );
	m_fSync[5][ 4] = FLOATKEY(  1.79f,  0.00f );
	m_fSync[5][ 5] = FLOATKEY(  1.89f,  1.00f );
	m_fSync[5][ 6] = FLOATKEY(  2.09f,  0.00f );
	m_fSync[5][ 7] = FLOATKEY(  3.52f,  0.00f );
	m_fSync[5][ 8] = FLOATKEY(  3.72f,  1.00f );
	m_fSync[5][ 9] = FLOATKEY(  3.92f,  0.00f );
	m_fSync[5][10] = FLOATKEY(  4.87f,  0.00f );
	m_fSync[5][11] = FLOATKEY(  5.07f,  1.00f );
	m_fSync[5][12] = FLOATKEY(  5.27f,  0.00f );
	m_fSync[5][13] = FLOATKEY(  5.53f,  0.00f );
	m_fSync[5][14] = FLOATKEY(  5.73f,  1.00f );
	m_fSync[5][15] = FLOATKEY(  5.93f,  0.00f );
	m_fSync[5][16] = FLOATKEY( 12.76f,  0.00f );
	m_fSync[5][17] = FLOATKEY( 12.96f,  1.00f );
	m_fSync[5][18] = FLOATKEY( 13.16f,  0.00f );
	m_fSync[5][19] = FLOATKEY( 13.66f,  0.00f );
	m_fSync[5][20] = FLOATKEY( 13.86f,  1.00f );
	m_fSync[5][21] = FLOATKEY( 14.06f,  0.00f );
	m_fSync[5][22] = FLOATKEY( 14.53f,  0.00f );
	m_fSync[5][23] = FLOATKEY( 14.73f,  1.00f );
	m_fSync[5][24] = FLOATKEY( 14.93f,  0.00f );
	m_fSync[5][25] = FLOATKEY( 15.47f,  0.00f );
	m_fSync[5][26] = FLOATKEY( 15.67f,  1.00f );
	m_fSync[5][27] = FLOATKEY( 15.87f,  0.00f );
	m_fSync[5][28] = FLOATKEY( 16.33f,  0.00f );
	m_fSync[5][29] = FLOATKEY( 16.53f,  1.00f );
	m_fSync[5][30] = FLOATKEY( 16.73f,  0.00f );
	m_fSync[5][31] = FLOATKEY( 19.74f,  0.00f );
	m_fSync[5][32] = FLOATKEY( 19.94f,  1.00f );
	m_fSync[5][33] = FLOATKEY( 20.07f,  0.00f );
	m_fSync[5][34] = FLOATKEY( 20.21f,  1.00f );
	m_fSync[5][35] = FLOATKEY( 20.41f,  0.00f );
	m_fSync[5][36] = FLOATKEY( 23.80f,  0.00f );
	m_fSync[5][37] = FLOATKEY( 24.00f,  1.00f );
	m_fSync[5][38] = FLOATKEY( 24.20f,  0.00f );
	m_fSync[5][39] = FLOATKEY( 25.34f,  0.00f );
	m_fSync[5][40] = FLOATKEY( 25.54f,  1.00f );
	m_fSync[5][41] = FLOATKEY( 25.64f,  0.00f );
	m_fSync[5][42] = FLOATKEY( 25.73f,  1.00f );
	m_fSync[5][43] = FLOATKEY( 25.93f,  0.00f );


	InitFloatSpline( 44, m_fSync[5] );


	m_dwKeyCount[0] = 39;
	m_dwKeyCount[1] = 50;
	m_dwKeyCount[2] = 53;
	m_dwKeyCount[3] = 60;
	m_dwKeyCount[4] = 38;
	m_dwKeyCount[5] = 44;
}	

CBlobsEfx::~CBlobsEfx()
{
	SAFE_RELEASE( m_pvbWireframeCube );
	SAFE_RELEASE( m_pvbBackFx );
	SAFE_RELEASE( m_pvbSyncSphere );
	SAFE_RELEASE( m_pibWireframeCube );
	SAFE_RELEASE( m_pibSyncSphere );

	SAFE_DELETE( m_piqFace );
	SAFE_DELETE( m_piqVis );
	SAFE_DELETE( m_piqDispaly );
}


// blob spline load!!!
VOID CBlobsEfx::LoadSplines()
{
	FILE*					in = fopen( "data\\misc\\blobs.splines", "rt" );
	CHAR					line[256];
	DWORD					dwCount;

	FLOAT					fTime;
	he3d_CVector			v;

	for( DWORD i = 0 ; i < BLOBSPLINES ; i++ )
	{
		dwCount = 0;			
		
		while( 1 )
		{
			fgets( line, 255, in );			

			if( !strcmp( line, "\n" ) || !strcmp( line, "" ) || line[0] == '%')
				continue;

			if( !strnicmp( line, "END", 3 ) )
				break;			

			sscanf( line, "%f: %f, %f, %f\n", &fTime, &v.x, &v.y, &v.z );			
			m_vSpline[i][dwCount++] = VECTORKEY( fTime, v );						
		}				

		m_dwBlobSplineKeyCount[i] = dwCount;
		InitVectorSpline( dwCount, m_vSpline[i] );
	}

	fclose( in );
}

BOOL CBlobsEfx::UpdateFrame( FLOAT fTime )
{
	// standard setup

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 30.0f, 0.75f, 1.0f, 500.0f ) );
	m_pDevice->SetTransform( D3DTS_VIEW, CameraMtx( he3d_CVector( 0, 0, -10 ), he3d_CVector( 0, 0, 3 ), 0 ) );		

	m_mtxBlobs = RotationMtx( fTime*0.25f, -fTime*0.5f, fTime*0.2f )*TranslationMtx( -1.0f, 0.0f, 0.0f );
	m_mtxGrid = ScaleMtx( 0.01f )*RotationMtx( fTime*0.25f, -fTime*0.5f, fTime*0.2f )*TranslationMtx( -1.0f, 0.0f, 0.0f );
	m_mtxSphere = RotationMtx( -fTime*0.35f, fTime*0.4f, fTime*0.3f );

	m_mtxBackFx[0] = ZRotationMtx( fTime*0.15f )*YRotationMtx( -0.50f )*TranslationMtx( -1.20f, 0, -8.0f );
	m_mtxBackFx[1] = ZRotationMtx( fTime*0.20f )*YRotationMtx(  0.20f )*TranslationMtx( -1.20f, 0, -7.5f );
	m_mtxBackFx[2] = ZRotationMtx( fTime*0.30f )*TranslationMtx( -1.20f, 0, -6.0f )*YRotationMtx( 0.15f );
	m_mtxBackFx[3] = ZRotationMtx( fTime*0.35f )*TranslationMtx( -1.20f, 0, -5.0f )*YRotationMtx( 0.10f );
	m_mtxBackFx[4] = ZRotationMtx( fTime*0.40f )*TranslationMtx( -1.10f, 0, -4.0f )*YRotationMtx( 0.05f );
	
	D3DMATERIAL8			d3dmat;
	
	d3dmat.Ambient.r = 1.0f;
	d3dmat.Ambient.g = 1.0f;
	d3dmat.Ambient.b = 1.0f;
	d3dmat.Diffuse.r = 0.4f;
	d3dmat.Diffuse.g = 0.4f;
	d3dmat.Diffuse.b = 0.4f;
	d3dmat.Emissive.r = 0.1f;
	d3dmat.Emissive.g = 0.1f;
	d3dmat.Emissive.b = 0.1f;
	d3dmat.Specular.r = 1.0f;
	d3dmat.Specular.g = 1.0f;
	d3dmat.Specular.b = 1.0f;
	d3dmat.Power = 100.0f;

	m_pDevice->SetMaterial( &d3dmat );

	D3DLIGHT8				d3dlit;
	
	ZeroMemory( &d3dlit, sizeof(D3DLIGHT8) );

	d3dlit.Type = D3DLIGHT_POINT;	
	d3dlit.Attenuation0 = 1.0f;
	d3dlit.Range = LIGHT_RANGE_MAX;

	d3dlit.Position.x = -150;
	d3dlit.Position.y = 70;
	d3dlit.Position.z = -100;

	d3dlit.Specular.r = 1.0f;
	d3dlit.Specular.g = 1.0f;
	d3dlit.Specular.b = 1.0f;
	d3dlit.Diffuse.r = 1.0f;
	d3dlit.Diffuse.g = 1.0f;
	d3dlit.Diffuse.b = 1.0f;

	m_pDevice->SetLight( 0, &d3dlit );

	d3dlit.Position.x = 100;
	d3dlit.Position.y = -50;
	d3dlit.Position.z = -100;

	m_pDevice->SetLight( 1, &d3dlit );		

	for( DWORD i = 0 ; i < BLOBSPLINES ; i++ )		
		m_b3dBlobs[i].m_vPos = GetVectorSplineValue( fTime, m_dwBlobSplineKeyCount[i], m_vSpline[i] );				

	m_bsSystem.CalculateDensity();

	PSIMPLEVERTEX			pVertices;
	he3d_CVector			v, vert;	
	FLOAT					length;

	v = m_vEmiterPos*RotationMtx( 0.5f*fTime, -0.5f*fTime, 0.7f*fTime );	

	m_pvbWireframeCube->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 1000 ; i++ )
	{
		vert = m_vCube[i] - v;		
		length = (vert.x*vert.x + vert.y*vert.y + vert.z*vert.z);

		if( length >= 0.05f )
			vert = ( 0.1f/length )*vert + m_vCube[i];
		else
			vert = m_vCube[i];

		pVertices[i].m_vPos.x = vert.x;
		pVertices[i].m_vPos.y = vert.y;
		pVertices[i].m_vPos.z = vert.z;
	}

	m_pvbWireframeCube->Unlock();

	FLOAT					fAlpha;

	if( fTime > 11.0f )
	{
		fAlpha = CLAMPALPHA( 255.0f*sinf( (fTime - 11.0f)*H_PI*0.2f ) );

		m_piqFace->SetAlpha( (DWORD)fAlpha );
		m_piqVis->SetAlpha( (DWORD)fAlpha );

		fAlpha = ( fTime - 11.0f )*0.2f;

		m_piqFace->Resize( 256.0f - 64.0f - 320.0f*fAlpha, 256.0f - 64.0f - 320.0f*fAlpha, 256.0f + 64.0f + 320.0f*fAlpha, 256.0f + 64.0f + 320.0f*fAlpha );

		if( fTime > 20.0f )
			m_piqVis->Resize( 768.0f - 320*fAlpha, 512.0f - 160.0f*fAlpha, -256.0f + 320*fAlpha, 160.0f*fAlpha );
		else
			m_piqVis->Resize( -256.0f + 320*fAlpha, 160.0f*fAlpha, 768.0f - 320*fAlpha, 512.0f - 160.0f*fAlpha );
	}
	else
	{
		m_piqFace->SetAlpha( 0x0 );
		m_piqVis->SetAlpha( 0x0 );

		m_piqFace->Resize( 0.0f, 0.0f, 0.0f, 0.0f );
		m_piqVis->Resize( 0.0f, 0.0f, 0.0f, 0.0f );
	}

	// sync sphere update !!!!

	FLOAT					fSync[6];
	FLOAT					fRGB[6][3];
								
	fRGB[0][0] = 1.0f; fRGB[0][1] = 0.8f; fRGB[0][2] = 0.8f;
	fRGB[1][0] = 0.8f; fRGB[1][1] = 1.0f; fRGB[1][2] = 0.8f;
	fRGB[2][0] = 0.8f; fRGB[2][1] = 0.8f; fRGB[2][2] = 1.0f;
	fRGB[3][0] = 1.0f; fRGB[3][1] = 0.8f; fRGB[3][2] = 0.8f;
	fRGB[4][0] = 0.8f; fRGB[4][1] = 1.0f; fRGB[4][2] = 0.8f;
	fRGB[5][0] = 0.8f; fRGB[5][1] = 0.8f; fRGB[5][2] = 1.0f;

	DWORD					dwColor;
	FLOAT					fCoeff;
	FLOAT					fR, fG, fB;
	

	for( i = 0 ; i < 6 ; i++ )
		fSync[i] = GetFloatSplineValue( fTime, m_dwKeyCount[i], m_fSync[i] );

	m_pvbSyncSphere->Lock( 38*4*sizeof(SIMPLEVERTEX), 38*4*sizeof(SIMPLEVERTEX), (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 38 ; i++ )
	{
		fCoeff = fSync[m_dwSyncIndex[i]];

		fR = CLAMPALPHA( 255.0f*fRGB[m_dwSyncIndex[i]][0]*fCoeff );
		fG = CLAMPALPHA( 255.0f*fRGB[m_dwSyncIndex[i]][1]*fCoeff );
		fB = CLAMPALPHA( 255.0f*fRGB[m_dwSyncIndex[i]][2]*fCoeff );
		
		dwColor = D3DCOLOR_XRGB( (DWORD)fR, (DWORD)fG, (DWORD)fB );

		*(pVertices++) = SIMPLEVERTEX( m_vSphere[i][0] + fCoeff*m_vSphereVector[i], dwColor );
		*(pVertices++) = SIMPLEVERTEX( m_vSphere[i][1] + fCoeff*m_vSphereVector[i], dwColor );
		*(pVertices++) = SIMPLEVERTEX( m_vSphere[i][2] + fCoeff*m_vSphereVector[i], dwColor );
		*(pVertices++) = SIMPLEVERTEX( m_vSphere[i][3] + fCoeff*m_vSphereVector[i], dwColor );
	}

	m_pvbSyncSphere->Unlock();

	return TRUE;
}

BOOL CBlobsEfx::RenderEfx()
{
	m_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0xffffff, 1.0f, 0 );		
	
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );

	m_pDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_STENCILREF, 0x1 );
	m_pDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE );	

	m_pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_ALPHAREF, 0x80 );
	m_pDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );

	m_pDevice->SetTexture( 0, GetTexture( "dispmask.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );

	m_piqDispaly->Render( m_pDevice );

	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );

	m_pDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );	

	m_pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_ALWAYS );

	m_pDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL );	

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

	m_pDevice->SetTexture( 0, GetTexture( "backfx.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );

	m_pDevice->SetVertexShader( FVF_LVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbBackFx, sizeof(LVERTEX) );

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 30.0f, 0.35f, 1.0f, 500.0f ) );

	for( DWORD i = 0 ; i < 5 ; i++ )
	{
		m_pDevice->SetTransform( D3DTS_WORLD, ScaleMtx( 2.0f )*m_mtxBackFx[i]*TranslationMtx( 0, 0, 2 ) );
		m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
	}

	// wireframe cube
	
	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );	

	m_pDevice->SetTexture( 0, NULL );	

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 30.0f, 0.75f, 1.0f, 500.0f ) );
	m_pDevice->SetTransform( D3DTS_WORLD, ScaleMtx( 5.0f )*m_mtxBlobs );	

	m_pDevice->SetVertexShader( FVF_SIMPLEVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbWireframeCube, sizeof(SIMPLEVERTEX) );
	m_pDevice->SetIndices( m_pibWireframeCube, 0 );
	m_pDevice->DrawIndexedPrimitive( D3DPT_LINELIST, 0, 1000, 0, 2700 );		
	
	//sync sphere!

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_EQUAL );	
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

	m_pDevice->SetTransform( D3DTS_WORLD, ScaleMtx( 0.5f )*m_mtxSphere*TranslationMtx( 1.4f, -1.35f, 0.0f ) );	

	m_pDevice->SetStreamSource( 0, m_pvbSyncSphere, sizeof(SIMPLEVERTEX) );
	m_pDevice->SetIndices( m_pibSyncSphere, 0 );
	m_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 8*38, 0, 38*12 );

	m_pDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );

	// display !!!			

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );

	m_pDevice->SetTexture( 0, GetTexture( "display3.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );

	m_piqDispaly->Render( m_pDevice );

	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );	

	// blobs & grid
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );	

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 30.0f, 0.75f, 1.0f, 500.0f ) );

	m_pDevice->SetTexture( 0, GetTexture( "env.jpg" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );

	m_pDevice->SetTransform( D3DTS_TEXTURE0, ScaleMtx( 0.5f )*TranslationMtx( 0.5f, 0.5f, 0.5f  ) );
	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxBlobs );

	m_bsSystem.Render( m_pDevice );

	m_pDevice->SetTexture( 0, NULL );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
	m_pDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );		

	m_pDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE );
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	m_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );		
	m_pDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );

	m_pDevice->LightEnable( 0, TRUE );
	m_pDevice->LightEnable( 1, TRUE );

	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxGrid );	

	m_smGrid.Render( m_pDevice );

	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );		
	m_pDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_NORMALIZENORMALS, FALSE);

	m_pDevice->LightEnable( 0, FALSE );
	m_pDevice->LightEnable( 1, FALSE );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

	m_pDevice->SetTexture( 0, GetTexture( "vis.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );

	m_piqVis->Render( m_pDevice );
	
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

	m_pDevice->SetTexture( 0, GetTexture( "face.jpg" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );

	m_piqFace->Render( m_pDevice );

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
	m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );


	
	return TRUE;
}


